package sicnu.cs.aps.common.exceptions;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.mail.MailSendException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.validation.BindingResult;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import sicnu.cs.aps.common.ResultInfo;
import sicnu.cs.aps.common.ResultInfoUtil;
import sicnu.cs.aps.common.enums.ResultEnum;

import javax.crypto.BadPaddingException;
import java.util.Objects;

/**
 * @author CaiKe
 * 2021/9/7
 */
@ControllerAdvice
@Slf4j
public class RuntimeExceptionHandler {

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResultInfo<Void> handlerGlobalException(Exception exception) {
        log.error("Exception", exception);
        return ResultInfoUtil.buildError("服务器异常");
    }

    /**
     * 处理访问权限不足的情况
     *
     * @param exception 异常信息
     * @return 返回结果
     */
    @ExceptionHandler(AccessDeniedException.class)
    @ResponseBody
    public ResultInfo<Void> handlerGlobalException(AccessDeniedException exception) {
        return ResultInfoUtil.buildError(ResultEnum.FORBIDDEN, exception.getMessage());
    }

    /**
     * 拦截参数校验的异常
     *
     * @param e 校验异常
     * @return 返回结果
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ResultInfo<Void> notValidExceptionHandle(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        Objects.requireNonNull(bindingResult.getFieldError());
        return ResultInfoUtil.buildError(ResultEnum.ERROR,
                bindingResult.getFieldError().getField() + " " + bindingResult.getFieldError().getDefaultMessage());
    }

    /**
     * 处理邮件发送失败的异常
     *
     * @param e 邮件发送失败异常
     * @return 返回结果
     */
    @ExceptionHandler(MailSendException.class)
    @ResponseBody
    public ResultInfo<Void> mailSendExceptionHandle(MailSendException e) {
        return ResultInfoUtil.buildError("MESSAGE SEND FAIL");
    }

    /**
     * 处理邮件发送失败的异常
     *
     * @param e 邮件发送失败异常
     * @return 返回结果
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseBody
    public ResultInfo<Void> httpMessageNotReadableExceptionHandle(HttpMessageNotReadableException e) {
        return ResultInfoUtil.buildError("JSON PARSE ERROR");
    }

    @ExceptionHandler(BadPaddingException.class)
    @ResponseBody
    public ResultInfo<Void> keyEncryptException(BadPaddingException e) {
        return ResultInfoUtil.buildError("KEY DECRYPT ERROR");
    }
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    @ResponseBody
    public ResultInfo<Void> methodNotSupportedExceptionHandle(HttpRequestMethodNotSupportedException e){
        return ResultInfoUtil.buildError("不支持该请求方式");
    }
}